unit uEditMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ExtCtrls, Buttons, Menus, uChoices,
  System.Generics.Collections, Vcl.CheckLst, Vcl.Imaging.jpeg,
  Vcl.Imaging.pngimage;

type
  TfrmEditMain = class(TForm)
    lbQuestions: TListBox;
    btnAddBool: TSpeedButton;
    btnAddSingleChoice: TSpeedButton;
    btnAddMultipleChoice: TSpeedButton;
    btnRemove: TSpeedButton;
    btnEdit: TSpeedButton;
    imDirty: TImage;
    Panel1: TPanel;
    Panel2: TPanel;
    btnSave: TSpeedButton;
    cb: TBitBtn;
    OB: TBitBtn;
    btnAssociate: TSpeedButton;
    btnCancelFileAssociation: TSpeedButton;
    btnImport: TSpeedButton;
    od: TOpenDialog;
    btnConcat: TSpeedButton;
    procedure FormCreate(Sender: TObject);
    procedure cbClick(Sender: TObject);
    procedure R1Change(Sender: TObject);
    procedure R2Change(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure _F1OBClick(Sender: TObject);
    procedure R2KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure btnAddBoolClick(Sender: TObject);
    procedure btnAddSingleChoiceClick(Sender: TObject);
    procedure btnAddMultipleChoiceClick(Sender: TObject);
    procedure btnRemoveClick(Sender: TObject);
    procedure btnEditClick(Sender: TObject);
    procedure _F1btnSaveClick(Sender: TObject);
    procedure lbQuestionsClick(Sender: TObject);
    procedure OBClick(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
    procedure btnAssociateClick(Sender: TObject);
    procedure btnCancelFileAssociationClick(Sender: TObject);
    procedure btnImportClick(Sender: TObject);
    procedure btnConcatClick(Sender: TObject);
  private
    { Private declarations }
  public
    procedure SaveFile;
    procedure loadfile;
    procedure dirty;
    function convertCheckBoxListToIntegerList( c: TCheckListBox ): TList<Integer>;
    procedure convertIntegerListToCheckBoxList( il: TList<Integer>; c: TCheckListBox );
    procedure addSingleChoice(d: String; a: Byte; k: String; o: String = '');
    procedure addMultiChoice(d: String; a: TList<Integer>; o: String );
    { Public declarations }
  end;
const
 nf='New.sf';
var
  frmEditMain: TfrmEditMain;
  f:TextFile;
  n,l,m:byte;
  fn:string;
  ext:string='.sf';
  vert:0..1;
  SCTRL:boolean=false;
  choices: TList<TChoice>;

implementation

uses uBool, uMultipleChoice, uChoice, Registry;

{$R *.dfm}

procedure TfrmEditMain.FormCreate(Sender: TObject);
begin
  fn := paramstr(1);
  if fn='' then
    fn := nf;
  Application.Title:=fn;
  caption:=fn;
  choices := TList<TChoice>.Create();
  if ParamCount > 1 then
    if ParamStr(2) = 'import1' then begin
      choices := TChoicesUtil.TryImportFromFile(ParamStr(3));
      SaveFile;
      if (ParamCount > 3) and (ParamStr(4) = 'terminate') then
        Application.Terminate;
    end;
end;

procedure TfrmEditMain.addMultiChoice(d: String; a: TList<Integer>; o: String);
var
  c: TChoice;
  i: Integer;
begin
  c := TMultipleChoice.Create( d, a, o);
  i := choices.Add(c);
  lbQuestions.ItemIndex := lbQuestions.Items.AddObject( IntToStr(i + 1) + ': ' + d, c );
end;

procedure TfrmEditMain.addSingleChoice(d: String; a: Byte; k: String; o: String = '');
var
  c: TChoice;
  i: Integer;
begin
  c := TSingleChoice.Create( d, a, k, o);
  i := choices.Add(c);
  lbQuestions.ItemIndex := lbQuestions.Items.AddObject( IntToStr(i + 1) + ': ' + d, c );
end;

procedure TfrmEditMain.btnAddBoolClick(Sender: TObject);
begin
  frmBool.memDescription.Text := '';
  frmBool.rgChoices.ItemIndex := -1;
  frmBool.Caption := 'New Boolean Choice Question';
  if frmBool.ShowModal = mrOk then begin
    addSingleChoice(
      frmBool.memDescription.Text,
      frmBool.rgChoices.ItemIndex,
      'b',
      frmBool.rgChoices.Items.Text
    );
  end;
  Dirty;
end;

procedure TfrmEditMain.btnAddMultipleChoiceClick(Sender: TObject);
begin
  frmMultipleChoice.memDescription.Text := '';
  frmMultipleChoice.clbChoices.Clear;
  frmMultipleChoice.edtOption.Text := '';
  frmMultipleChoice.btnEdit.Enabled := False;
  frmMultipleChoice.btnRemove.Enabled := False;
  frmMultipleChoice.Caption := 'New Multiple Choice Question';
  if frmMultipleChoice.ShowModal = mrOk then begin
    addMultiChoice(
      frmMultipleChoice.memDescription.Text,
      convertCheckBoxListToIntegerList( frmMultipleChoice.clbChoices ),
      frmMultipleChoice.clbChoices.Items.Text
    );
  end;
  Dirty;
end;

procedure TfrmEditMain.btnAddSingleChoiceClick(Sender: TObject);
begin
  frmChoice.memDescription.Text := '';
  frmChoice.rgChoices.Items.Clear;
  frmChoice.edtOption.Text := '';
  frmChoice.btnEdit.Enabled := False;
  frmChoice.btnRemove.Enabled := False;
  frmChoice.Caption := 'New Single Choice Question';
  if frmChoice.ShowModal = mrOk then begin
    addSingleChoice(
      frmChoice.memDescription.Text,
      frmChoice.rgChoices.ItemIndex,
      's',
      frmChoice.rgChoices.Items.Text
    );
  end;
  Dirty;
end;

procedure TfrmEditMain.btnAssociateClick(Sender: TObject);
begin
  try
    CreateSalesforceFileEditAssociation();
  except on E: ERegistryException do
    ShowMessage('Not enough rights to write to registry.'#13#10'Please rerun as administrator');
  end;
end;

procedure TfrmEditMain.btnCancelFileAssociationClick(Sender: TObject);
var
  Response, Exists, Removed: String;
begin
  Response := CancelSalesforceFileAssociation();
  Exists := Copy(Response, 1, 3);
  Removed := Copy(Response, 4, 3);
  //ShowMessage('Response: ' + Response);
  if Exists = '000' then
    ShowMessage('Error: Program has not been associated or file association has been already canceled')
  else
  if Removed = '000' then
    ShowMessage('Not enough rights to write to registry.'#13#10'Please rerun as administrator');
end;

procedure TfrmEditMain.btnConcatClick(Sender: TObject);
var
  i, last: Integer;
  choices2: TList<TChoice>;
begin
  if not od.Execute then
    Exit;
  showMessage(od.FileName);
  choices2 := TChoicesUtil.LoadFileEdit(od.FileName);
  showMessage(  IntToStr(choices2.Count));
  last := choices.Count + 1;
  for I := 0 to choices2.Count - 1 do
    choices.add( choices2[i] );
  for I := 0 to choices2.Count - 1 do
    lbQuestions.Items.AddObject( IntToStr(last + i) + ': ' + choices2[i].description, choices2[i] );
end;

procedure TfrmEditMain.btnEditClick(Sender: TObject);
var
  index: Integer;
begin
  index := lbQuestions.ItemIndex;
  if choices[ index ].kind = 'b' then begin
    frmBool.memDescription.Text := choices[ index ].description;
    frmBool.rgChoices.ItemIndex := TSingleChoice(choices[ index ]).correctAnswer;
    frmBool.Caption := choices[ index ].description;
    if frmBool.ShowModal = mrOk then begin
      choices[ index ].description := frmBool.memDescription.Text;
      TSingleChoice(choices[ index ]).correctAnswer := frmBool.rgChoices.ItemIndex;
    end;
  end else if choices[ index ].kind = 's' then begin
    frmChoice.memDescription.Text := choices[ index ].description;
    frmChoice.rgChoices.Items.Text := choices[ index ].options;
    frmChoice.rgChoices.ItemIndex := TSingleChoice(choices[ index ]).correctAnswer;
    frmChoice.Caption := choices[ index ].description;
    if frmChoice.ShowModal = mrOk then begin
      choices[ index ].description := frmChoice.memDescription.Text;
      TSingleChoice(choices[ index ]).correctAnswer := frmChoice.rgChoices.ItemIndex;
      choices[ index ].options := frmChoice.rgChoices.Items.Text;
    end;
  end else if choices[ index ].kind = 'm' then begin
    frmMultipleChoice.memDescription.Text := choices[ index ].description;
    frmMultipleChoice.clbChoices.Items.Text := choices[ index ].options;
    convertIntegerListToCheckBoxList( TMultipleChoice(choices[ index ]).correctAnswer, frmMultipleChoice.clbChoices );
    frmMultipleChoice.Caption := choices[ index ].description;
    if frmMultipleChoice.ShowModal = mrOk then begin
      choices[ index ].description := frmMultipleChoice.memDescription.Text;
      TMultipleChoice(choices[ index ]).correctAnswer := convertCheckBoxListToIntegerList( frmMultipleChoice.clbChoices );
      choices[ index ].options := frmMultipleChoice.clbChoices.Items.Text;
    end;
  end;
  lbQuestions.Items[ index ] := IntToStr(index + 1) + ': ' + choices[ index ].description;
  Dirty;
 {
  case choices[ index ].kind[1] of
    'b': frmModal := frmBool;
    's': frmModal := ;
    'm': frmModal := ;
  end;
  case choices[ index ].kind[1] of
    'b': t := TfrmBool;
    's': t := TfrmChoice;
    'm': t := TfrmMultipleChoice;
  end;
  (frmModal as t).memDescription.Text := '';}
  //updateChoice( index, frmModal.memDescription.Text, frmModal.rgChoices.ItemIndex, 's' );
end;

procedure TfrmEditMain.btnImportClick(Sender: TObject);
var
  i: Integer;
begin
  if not od.Execute then
    Exit;
  FreeAndNil(choices);
  choices := TChoicesUtil.TryImportFromFile(od.FileName);
  lbQuestions.Items.Clear;
  for I := 0 to choices.Count - 1 do
    lbQuestions.Items.AddObject( IntToStr(choices.Count + i + 1) + ': ' + choices[i].description, choices[i] );
  SaveFile;
end;

procedure TfrmEditMain.btnRemoveClick(Sender: TObject);
var
  index: Integer;
begin
  index := lbQuestions.ItemIndex;
  choices.Delete( index );
  lbQuestions.Items.Delete( index );
  Dirty;
end;

procedure TfrmEditMain.btnSaveClick(Sender: TObject);
begin
  SaveFile;
end;

procedure TfrmEditMain.cbClick(Sender: TObject);
begin
 close;
end;

function TfrmEditMain.convertCheckBoxListToIntegerList(
  c: TCheckListBox): TList<Integer>;
var
  i: Integer;
begin
  Result := TList<Integer>.Create();
  for i := 0 to c.Items.Count - 1 do begin
    if c.Checked[i] then
      Result.Add( i );
  end;

end;

procedure TfrmEditMain.convertIntegerListToCheckBoxList(il: TList<Integer>;
  c: TCheckListBox);
var
  i: Integer;
begin
  for i := 0 to c.Items.Count - 1 do begin
    c.Checked[i] := False;
  end;
  for i := 0 to il.Count - 1 do begin
    c.Checked[il[i]] := True;
  end;
end;

procedure TfrmEditMain.dirty;
begin
  imDirty.Visible := True;
end;

procedure TfrmEditMain.R1Change(Sender: TObject);
begin
 Application.Title:=fn+'*';
 caption:=fn+'*';
// R2.CaretPos:=R1.CaretPos
end;

procedure TfrmEditMain.R2Change(Sender: TObject);
begin
 Application.Title:=fn+'*';
 caption:=fn+'*';
end;

procedure TfrmEditMain.FormShow(Sender: TObject);
begin
  LoadFile
end;

procedure TfrmEditMain.SaveFile;
var
 i,j:Integer;
 sl: TStringList;
 il: TList<Integer>;
begin
  fn:=ChangeFileExt(fn,ext);
  AssignFile(f,fn);
  rewrite(f);
  try

  writeln(f, choices.Count);
  sl := TStringList.Create;
  //il := TList<Integer>.Create;
  for i := 0 to choices.Count - 1 do begin
    writeln(f, choices[i].kind);
    sl.Text := choices[i].description;
    writeln(f, sl.Count);
    write(f, sl.Text);
    if choices[i].kind <> 'b' then begin
      sl.Text := choices[i].options;
      writeln(f, sl.Count);
      write(f, sl.Text);
    end;

  end;
  for i := 0 to choices.Count - 1 do begin
    if choices[i].kind = 'm' then begin
      il := TMultipleChoice(choices[i]).correctAnswer;
      writeln(f, il.Count);
      if il.Count > 0 then begin
        for j := 0 to il.Count - 1 do
          write(f, il[j], ' ');
        writeln(f);
      end;

    end else begin
      writeln(f, TSingleChoice(choices[i]).correctAnswer);
    end;
  end;

  finally
    imDirty.Visible := False;
    closeFile(f);
  end;


 caption:=fn
end;

procedure TfrmEditMain._F1btnSaveClick(Sender: TObject);
begin
  savefile
end;

procedure TfrmEditMain._F1OBClick(Sender: TObject);
begin
  SaveFile;
  close;
end;

procedure TfrmEditMain.lbQuestionsClick(Sender: TObject);
var
  e: Boolean;
begin
  e := (lbQuestions.ItemIndex >=0) and (lbQuestions.ItemIndex < lbQuestions.Items.Count);
  btnRemove.Enabled := e;
  btnEdit.Enabled := e;
end;

procedure TfrmEditMain.loadfile;
var
  i: Integer;
  {i, j, l, m, n: Integer;

  kind, d, desc, opts: String;
  il: TList<Integer>;
  success: Boolean;
  s: String;}
begin
  choices := TChoicesUtil.LoadFileEdit(fn);
  for i := 0 to choices.Count - 1 do
    lbQuestions.Items.AddObject( IntToStr(i + 1) + ': ' + choices[i].description, choices[i] );


  Application.Title:=fn;
  caption:=fn;
  lbQuestions.ItemIndex := -1;
end;

procedure TfrmEditMain.OBClick(Sender: TObject);
begin
  SaveFile;
  close;
end;

procedure TfrmEditMain.R2KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
     SCTRL:=false

end;

end.
